home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 3_1_3 / sys / amiga / amidos.c next >
Encoding:
C/C++ Source or Header  |  1993-07-03  |  10.2 KB  |  490 lines

  1. /*    SCCS Id: @(#)amidos.c     3.1    93/01/08
  2. /* Copyright (c) Olaf Seibert, Nijmegen, The Netherlands, 1988,1990.    */
  3. /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991, 1992, 1993.  */
  4. /* NetHack may be freely redistributed.  See license for details.    */
  5.  
  6. /*
  7.  * An assortment of imitations of cheap plastic MSDOS and Unix functions.
  8.  */
  9.  
  10. #include "hack.h"
  11. #include "winami.h"
  12.  
  13. /* Defined in config.h, let's undefine it here (static function below) */
  14. #undef strcmpi
  15.  
  16. #include <libraries/dos.h>
  17. #include <exec/execbase.h>
  18. #include <intuition/intuition.h>
  19.  
  20. #undef COUNT
  21. #ifdef __SASC_60
  22. # include <proto/exec.h>
  23. # include <proto/dos.h>
  24. #endif
  25.  
  26. #ifdef AZTEC_50
  27. # include <functions.h>
  28. # undef strcmpi
  29. #endif
  30.  
  31. /* Prototypes */
  32. #include "Amiga:winami.p"
  33. #include "Amiga:amiwind.p"
  34. #include "Amiga:amidos.p"
  35.  
  36. extern char Initialized;
  37. extern struct window_procs amii_procs;
  38.  
  39. #ifndef __SASC_60
  40. int Enable_Abort = 0;   /* for stdio package */
  41. #endif
  42.  
  43. /* Initial path, so we can find NetHack.cnf */
  44. char PATH[PATHLEN] = "Ram:;df0:;NetHack:";
  45.  
  46. static boolean record_exists(void);
  47.  
  48. void
  49. flushout()
  50. {
  51.     (void) fflush(stdout);
  52. }
  53.  
  54. #ifndef getuid
  55. getuid()
  56. {
  57.     return 1;
  58. }
  59. #endif
  60.  
  61. #ifndef getlogin
  62. char *
  63. getlogin()
  64. {
  65.     return ((char *) NULL);
  66. }
  67. #endif
  68.  
  69. #ifndef AZTEC_50
  70. int
  71. abs(x)
  72. int x;
  73. {
  74.     return x < 0? -x: x;
  75. }
  76. #endif
  77.  
  78. #ifdef SHELL
  79. int
  80. dosh()
  81. {
  82.     int i;
  83.     char buf[ 500 ];
  84.     extern struct ExecBase *SysBase;
  85.  
  86.     /* Only under 2.0 and later ROMs do we have System() */
  87.     if( SysBase->LibNode.lib_Version >= 37 && !amibbs)
  88.     {
  89.     getlin("Enter CLI Command...", buf );
  90.     i = System( buf, NULL );
  91.     }
  92.     else
  93.     {
  94.     i = 0;
  95.     pline("No mysterious force prevented you from using multitasking.");
  96.     }
  97.     return i;
  98. }
  99. #endif /* SHELL */
  100.  
  101. #ifdef MFLOPPY
  102. # include <ctype.h>
  103.  
  104. # define Sprintf (void) sprintf
  105.  
  106. #define EXTENSION   72
  107.  
  108. /*
  109.  *  This routine uses an approximation of the free bytes on a disk.
  110.  *  How large a file you can actually write depends on the number of
  111.  *  extension blocks you need for it.
  112.  *  In each extenstion block there are maximum 72 pointers to blocks,
  113.  *  so every 73 disk blocks have only 72 available for data.
  114.  *  The (necessary) file header is also good for 72 data block pointers.
  115.  */
  116. /* TODO: update this for FFS */
  117. long
  118. freediskspace(path)
  119. char *path;
  120. {
  121.     register long freeBytes = 0;
  122.     register struct InfoData *infoData; /* Remember... longword aligned */
  123.     char fileName[32];
  124.  
  125.     /*
  126.      *  Find a valid path on the device of which we want the free space.
  127.      *  If there is a colon in the name, it is an absolute path
  128.      *  and all up to the colon is everything we need.
  129.      *  Remember slashes in a volume name are allowed!
  130.      *  If there is no colon, it is relative to the current directory,
  131.      *  so must be on the current device, so "" is enough...
  132.      */
  133.     {
  134.     register char *colon;
  135.  
  136.     strncpy(fileName, path, sizeof(fileName) - 1);
  137.     fileName[31] = 0;
  138.     if (colon = index(fileName, ':'))
  139.     colon[1] = '\0';
  140.     else
  141.     fileName[0] = '\0';
  142.     }
  143.     {
  144.     BPTR fileLock;
  145.     infoData = (struct InfoData *) alloc(sizeof(struct InfoData));
  146.     if (fileLock = Lock(fileName, SHARED_LOCK)) {
  147.     if (Info(fileLock, infoData)) {
  148.         /* We got a kind of DOS volume, since we can Lock it. */
  149.         /* Calculate number of blocks available for new file */
  150.         /* Kludge for the ever-full VOID: (oops RAM:) device */
  151.         if (infoData->id_UnitNumber == -1 &&
  152.           infoData->id_NumBlocks == infoData->id_NumBlocksUsed) {
  153.         freeBytes = AvailMem(0L) - 64 * 1024L;
  154.             /* Just a stupid guess at the */
  155.             /* Ram-Handler overhead per block: */
  156.         freeBytes -= freeBytes/16;
  157.         } else {
  158.         /* Normal kind of DOS file system device/volume */
  159.         freeBytes = infoData->id_NumBlocks - infoData->id_NumBlocksUsed;
  160.         freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1);
  161.         freeBytes *= infoData->id_BytesPerBlock;
  162.         }
  163.         if (freeBytes < 0)
  164.         freeBytes = 0;
  165.     }
  166.     UnLock(fileLock);
  167.     }
  168.     free(infoData);
  169.     return freeBytes;
  170.     }
  171. }
  172.  
  173.  
  174. long
  175. filesize(file)
  176. char *file;
  177. {
  178.     register BPTR fileLock;
  179.     register struct FileInfoBlock *fileInfoBlock;
  180.     register long size = 0;
  181.  
  182.     fileInfoBlock = (struct FileInfoBlock *)alloc(sizeof(struct FileInfoBlock));
  183.     if (fileLock = Lock(file, SHARED_LOCK)) {
  184.     if (Examine(fileLock, fileInfoBlock)) {
  185.         size = fileInfoBlock->fib_Size;
  186.     }
  187.     UnLock(fileLock);
  188.     }
  189.     free(fileInfoBlock);
  190.     return size;
  191. }
  192.  
  193. void
  194. eraseall(path, files)
  195. const char *path, *files;
  196. {
  197.     BPTR dirLock, dirLock2;
  198.     struct FileInfoBlock *fibp;
  199.     int chklen;
  200. #ifdef BETA
  201.     if(files != alllevels)panic("eraseall");
  202. #endif
  203.     chklen=(int)index(files,'*')-(int)files;
  204.  
  205.     if (dirLock = Lock(path ,SHARED_LOCK)) {
  206.     dirLock2=DupLock(dirLock);
  207.     dirLock2= CurrentDir(dirLock2);
  208.     fibp=AllocMem(sizeof(struct FileInfoBlock),0);
  209.     if(fibp){
  210.         if(Examine(dirLock,fibp)){
  211.         while(ExNext(dirLock,fibp)){
  212.             if(!strncmp(fibp->fib_FileName,files,chklen)){
  213.             DeleteFile(fibp->fib_FileName);
  214.             }
  215.         }
  216.         }
  217.         FreeMem(fibp,sizeof(struct FileInfoBlock));
  218.     }
  219.     UnLock(dirLock);
  220.     UnLock(CurrentDir(dirLock2));
  221.     }
  222. }
  223.  
  224. /* This size makes that most files can be copied with two Read()/Write()s */
  225.  
  226. #define COPYSIZE    4096
  227.  
  228. char *CopyFile(from, to)
  229. const char *from, *to;
  230. {
  231.     register BPTR fromFile, toFile;
  232.     register char *buffer;
  233.     register long size;
  234.     char *error = NULL;
  235.  
  236.     buffer = (char *) alloc(COPYSIZE);
  237.     if (fromFile = Open(from, MODE_OLDFILE)) {
  238.     if (toFile = Open(to, MODE_NEWFILE)) {
  239.         while (size = Read(fromFile, buffer, (long)COPYSIZE)) {
  240.         if (size == -1){
  241.             error = "Read error";
  242.             break;
  243.         }
  244.         if (size != Write(toFile, buffer, size)) {
  245.             error = "Write error";
  246.             break;
  247.         }
  248.         }
  249.         Close(toFile);
  250.     } else
  251.         error = "Cannot open destination";
  252.     Close(fromFile);
  253.     } else
  254.     error = "Cannot open source (this should not occur)";
  255.     free(buffer);
  256.     return error;
  257. }
  258.  
  259.  
  260. /* this should be replaced */
  261. saveDiskPrompt(start)
  262. {
  263.     char buf[BUFSIZ], *bp;
  264.     BPTR fileLock;
  265.  
  266.     if (flags.asksavedisk) {
  267.         /* Don't prompt if you can find the save file */
  268.     if (fileLock = Lock(SAVEF, SHARED_LOCK)) {
  269.         UnLock(fileLock);
  270. #if defined(TTY_GRAPHICS)
  271.         if(windowprocs.win_init_nhwindows!=amii_procs.win_init_nhwindows)
  272.         clear_nhwindow( WIN_MAP );
  273. #endif
  274. #if defined(AMII_GRAPHICS)
  275.         if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)
  276.         clear_nhwindow( WIN_BASE );
  277. #endif
  278.         return 1;
  279.     }
  280.     pline( "If save file is on a SAVE disk, put that disk in now." );
  281.     if( strlen( SAVEF ) > QBUFSZ - 25 - 22 )
  282.         panic( "not enough buffer space for prompt" );
  283. /* THIS IS A HACK */
  284. #if defined(TTY_GRAPHICS)
  285.     if(windowprocs.win_init_nhwindows!=amii_procs.win_init_nhwindows){
  286.         getlin("File name ?",buf);
  287.         clear_nhwindow( WIN_MAP );
  288.     }
  289. #endif
  290. #if defined(AMII_GRAPHICS)
  291.     if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows){
  292.         getlind("File name ?", buf, SAVEF);
  293.         clear_nhwindow( WIN_BASE );
  294.     }
  295. #endif
  296.     clear_nhwindow( WIN_MESSAGE);
  297.     if (!start && *buf == '\033')
  298.         return 0;
  299.  
  300.     /* Strip any whitespace. Also, if nothing was entered except
  301.      * whitespace, do not change the value of SAVEF.
  302.      */
  303.     for (bp = buf; *bp; bp++) {
  304.         if (!isspace(*bp)) {
  305.         strncpy(SAVEF, bp, PATHLEN);
  306.         break;
  307.         }
  308.     }
  309.     }
  310.     return 1;
  311. }
  312.  
  313. /* Return 1 if the record file was found */
  314. static boolean
  315. record_exists()
  316. {
  317.     FILE *file;
  318.  
  319.     if (file = fopenp(RECORD, "r")) {
  320.     fclose(file);
  321.     return TRUE;
  322.     }
  323.     return FALSE;
  324. }
  325.  
  326. #ifdef MFLOPPY
  327. /*
  328.  * Under MSDOS: Prompt for game disk, then check for record file.
  329.  * For Amiga: do nothing, but called from restore.c
  330.  */
  331. void
  332. gameDiskPrompt(){}
  333. #endif
  334.  
  335. /*
  336.  * Add a slash to any name not ending in / or :.  There must
  337.  * be room for the /.
  338.  */
  339. void
  340. append_slash(name)
  341. char *name;
  342. {
  343.     char *ptr;
  344.  
  345.     if (!*name)return;
  346.  
  347.     ptr = eos(name) - 1;
  348.     if (*ptr != '/' && *ptr != ':') {
  349.     *++ptr = '/';
  350.     *++ptr = '\0';
  351.     }
  352. }
  353.  
  354.  
  355. void
  356. getreturn(str)
  357. const char *str;
  358. {
  359.     int ch;
  360.  
  361.     raw_printf("Hit <RETURN> %s.", str);
  362.     while ((ch = nhgetch()) != '\n' && ch != '\r' )
  363.     continue;
  364. }
  365.  
  366. /* Follow the PATH, trying to fopen the file.
  367.  */
  368. #define PATHSEP    ';'
  369.  
  370. FILE *
  371. fopenp(name, mode)
  372. register const char *name, *mode;
  373. {
  374.     register char *bp, *pp, lastch;
  375.     register FILE *fp;
  376.     register BPTR theLock;
  377.     char buf[BUFSIZ];
  378.  
  379.     /* Try the default directory first.  Then look along PATH.
  380.      */
  381.     strcpy(buf, name);
  382.     if (theLock = Lock(buf, SHARED_LOCK)) {
  383.     UnLock(theLock);
  384.     if (fp = fopen(buf, mode))
  385.         return fp;
  386.     }
  387.     pp = PATH;
  388.     while (pp && *pp) {
  389.     bp = buf;
  390.     while (*pp && *pp != PATHSEP){
  391.         if( bp > buf + BUFSIZ - 1 ) return( NULL );
  392.         lastch = *bp++ = *pp++;
  393.     }
  394.     if (lastch != ':' && lastch != '/' && bp != buf)
  395.         *bp++ = '/';
  396.     strcpy(bp, name);
  397.     if (theLock = Lock(buf, SHARED_LOCK)) {
  398.         UnLock(theLock);
  399.         if (fp = fopen(buf, mode)) return fp;
  400.     }
  401.     if (*pp)
  402.         pp++;
  403.     }
  404.     return NULL;
  405. }
  406. #endif /* MFLOPPY */
  407.  
  408. #ifdef CHDIR
  409.  
  410. /*
  411.  *  A not general-purpose directory changing routine.
  412.  *  Assumes you want to return to the original directory eventually,
  413.  *  by chdir()ing to orgdir.
  414.  *  Assumes -1 is not a valid lock, since 0 is valid.
  415.  */
  416.  
  417. #define NO_LOCK     ((BPTR) -1)
  418.  
  419. char orgdir[1];
  420. static BPTR OrgDirLock = NO_LOCK;
  421.  
  422. chdir(dir)
  423. const char *dir;
  424. {
  425.     if (dir == orgdir) {
  426.         /* We want to go back to where we came from. */
  427.     if (OrgDirLock != NO_LOCK) {
  428.         UnLock(CurrentDir(OrgDirLock));
  429.         OrgDirLock = NO_LOCK;
  430.     }
  431.     } else {
  432.         /*
  433.          * Go to some new place. If still at the original
  434.          * directory, save the FileLock.
  435.          */
  436.     BPTR newDir;
  437.  
  438.     if (newDir = Lock(dir, SHARED_LOCK)) {
  439.         if (OrgDirLock == NO_LOCK) {
  440.         OrgDirLock = CurrentDir(newDir);
  441.         } else {
  442.         UnLock(CurrentDir(newDir));
  443.         }
  444.     } else {
  445.         return -1;  /* Failed */
  446.     }
  447.     }
  448.     /* CurrentDir always succeeds if you have a lock */
  449.     return 0;
  450. }
  451.  
  452. #endif /* CHDIR */
  453.  
  454. /* Chdir back to original directory
  455.  */
  456. #undef exit
  457. void
  458. msexit(code)
  459. {
  460. #ifdef CHDIR
  461.     extern char orgdir[];
  462. #endif
  463.  
  464. #ifdef CHDIR
  465.     chdir(orgdir);      /* chdir, not chdirx */
  466. #endif
  467.  
  468. #ifdef AMII_GRAPHICS
  469.     if(windowprocs.win_init_nhwindows==amii_procs.win_init_nhwindows)
  470.     CleanUp();
  471. #endif
  472.     exit(code);
  473. }
  474.  
  475. int
  476. uptodate(fd)
  477. {
  478.     return(1);
  479. }
  480.  
  481. void
  482. regularize(s)    /* normalize file name - we don't like :'s or /'s */
  483. register char *s;
  484. {
  485.     register char *lp;
  486.  
  487.     while((lp = index(s, ':')) || (lp = index(s, '/')))
  488.     *lp = '_';
  489. }
  490.